package com.railwayservice.common.service;

import com.railwayservice.application.exception.AppException;
import com.railwayservice.messages.service.NoticeService;
import com.railwayservice.order.entity.MainOrder;
import com.railwayservice.order.service.MainOrderService;
import com.railwayservice.order.service.OrderStatic;
import com.railwayserviceWX.config.ConfigParser;
import com.railwayserviceWX.util.WechatPayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 定时任务以及初始化任务
 *
 * @author lid
 * @date 2017.3.31
 */
@Service
public class TimedTaskSchedule implements ApplicationListener<ContextRefreshedEvent> {

    private final Logger logger = LoggerFactory.getLogger(TimedTaskSchedule.class);

    private long orderOverTime = 10L;// 单位：分钟，会从配置文件读取

    private MainOrderService mainOrderService;

    private NoticeService noticeService;

    @Autowired
    public void setNoticeService(NoticeService noticeService) {
        this.noticeService = noticeService;
    }

    @Autowired
    public void setMainOrderService(MainOrderService mainOrderService) {
        this.mainOrderService = mainOrderService;
    }

    /**
     * 当bean装载完之后调用一次初始化任务
     * 获取所有等待商家接单状态的订单
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent arg0) {
        // 读取配置文件
        String orderOverTime = ConfigParser.getOrderOverTime();
        this.orderOverTime = Long.valueOf(orderOverTime);
    }

    @Scheduled(fixedRate = 60000L)   //每120秒执行一次
    public void acceptOrders() {
        logger.info("定时任务执行：处理待抢单超时订单");

        // 在这个时间线之前的订单才会被处理
        long timeLine = System.currentTimeMillis() - 60000L * orderOverTime;
        Date dateLine = new Date(timeLine);

        List<MainOrder> mainOrders = mainOrderService.findByCreateDateBeforeAndOrderStatus(
                dateLine, OrderStatic.MAINORDER_STATUS_ACCEPT);

        logger.info("待抢单超时订单个数：" + mainOrders.size());

        for (MainOrder mainOrder : mainOrders) {
            try { // 逐条处理，失败回滚，不影响其他订单处理。
                mainOrderOverTime(mainOrder);
            } catch (Exception e) {
                logger.info("订单超时处理异常：订单编号：" + mainOrder.getOrderNo(), e);
            }
        }
    }

    /**
     * 订单超时退款。
     *
     * @param order
     */
    @Transactional
    private void mainOrderOverTime(MainOrder order) {
        logger.info("order.getOrderStatus()：" + order.getOrderStatus() + " order.getPayStatus()："
                + order.getPayStatus() + " order.getCreateDate()" + order.getCreateDate());

        //商家已接单并且支付状态为未退款的订单
        if (OrderStatic.PAY_STATUS_REFUNDED != order.getPayStatus()) {
            logger.info("超时退款！退款的订单号：" + order.getOrderId());

            int totalMoney = order.getOrderTotalPrice().multiply(new BigDecimal("100")).intValue();
            logger.info("totalMoney：" + totalMoney);

            Map<String, Object> mapResult = new HashMap<String, Object>();

            try {
                mapResult = WechatPayUtil.refund(order.getTransactionId(),
                        order.getOrderNo(), order.getOrderNo(), totalMoney, totalMoney);
            } catch (Exception e) {
                logger.error("订单：" + order.getOrderNo() + " 退款调用微信支付接口异常：", e);
            }

            logger.info("mapResult:" + mapResult.toString());

            if ("SUCCESS".equals(mapResult.get("returnCode"))) {
                //设置订单状态为已退款，并设置退款单号和退款时间
                order.setPayStatus(OrderStatic.PAY_STATUS_REFUNDED);

                if (StringUtils.hasText(String.valueOf(mapResult.get("refund_id")))) {
                    order.setRefundId(String.valueOf(mapResult.get("refund_id")));
                }

                order.setOutRefundNo(order.getOrderNo());
                order.setRefundDate(new Date());
                order.setUpdateDate(new Date());
                order.setOrderStatus(OrderStatic.MAINORDER_STATUS_OVERTIME);
                mainOrderService.updateMainOrder(order);

                //发消息通知用户
                noticeService.sendOrderOverTime(order);
                logger.info(order.getOrderNo() + "订单状态已设置为超时并退款！");
            } else {
                throw new AppException("订单：" + order.getOrderNo() + " 退款失败：" + mapResult.get("return_msg"));
            }
        }
    }
}
